home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / src / winmenu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-22  |  17.9 KB  |  705 lines

  1. /* winmenu.c - command menu for windows
  2.  * 
  3.  *  Window Maker window manager
  4.  * 
  5.  *  Copyright (c) 1997, 1998 Alfredo K. Kojima
  6.  * 
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
  20.  *  USA.
  21.  */
  22.  
  23. #include "wconfig.h"
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <unistd.h>
  28. #include <string.h>
  29.  
  30. #include <X11/Xlib.h>
  31. #include <X11/Xutil.h>
  32.  
  33. #include "WindowMaker.h"
  34. #include "actions.h"
  35. #include "menu.h"
  36. #include "funcs.h" 
  37. #include "window.h"
  38. #include "client.h"
  39. #include "application.h"
  40. #include "keybind.h"
  41. #include "framewin.h"
  42. #include "workspace.h"
  43. #include "winspector.h"
  44. #include "dialog.h"
  45. #include "stacking.h"
  46. #include "icon.h"
  47.  
  48.  
  49. #define MC_MAXIMIZE    0
  50. #define MC_MINIATURIZE    1
  51. #define MC_SHADE    2
  52. #define MC_HIDE        3
  53. #define MC_MOVERESIZE    4
  54. #define MC_SELECT       5
  55. #define MC_DUMMY_MOVETO    6
  56. #define MC_PROPERTIES   7
  57. #define MC_OPTIONS    8
  58. #define MC_SHORTCUT    8
  59.  
  60. #define MC_CLOSE        9
  61. #define MC_KILL         10
  62.  
  63.  
  64. #define WO_KEEP_ON_TOP        0
  65. #define WO_KEEP_AT_BOTTOM    1
  66. #define WO_OMNIPRESENT        2
  67. #define WO_ENTRIES        3
  68.  
  69. /**** Global data ***/
  70. extern Time LastTimestamp;
  71. extern Atom _XA_WM_DELETE_WINDOW;
  72. extern Atom _XA_GNUSTEP_WM_MINIATURIZE_WINDOW;
  73.  
  74. extern WShortKey wKeyBindings[WKBD_LAST];
  75.  
  76. extern WPreferences wPreferences;
  77.  
  78. static void updateOptionsMenu(WMenu *menu, WWindow *wwin);
  79.  
  80. static void
  81. execWindowOptionCommand(WMenu *menu, WMenuEntry *entry)
  82. {
  83.     WWindow *wwin = (WWindow*)entry->clientdata;
  84.     
  85.     switch (entry->order) {
  86.      case WO_KEEP_ON_TOP:
  87.     if(wwin->frame->core->stacking->window_level!=WMFloatingLevel)
  88.         ChangeStackingLevel(wwin->frame->core, WMFloatingLevel);
  89.     else
  90.         ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
  91.     break;
  92.  
  93.      case WO_KEEP_AT_BOTTOM:
  94.     if(wwin->frame->core->stacking->window_level!=WMSunkenLevel)
  95.         ChangeStackingLevel(wwin->frame->core, WMSunkenLevel);
  96.     else
  97.         ChangeStackingLevel(wwin->frame->core, WMNormalLevel);
  98.     break;
  99.  
  100.      case WO_OMNIPRESENT:
  101.     wwin->flags.omnipresent^=1;
  102.     UpdateSwitchMenu(wwin->screen_ptr, wwin, ACTION_CHANGE_WORKSPACE);
  103.     break;
  104.     }
  105. }
  106.  
  107.  
  108. static void
  109. execMenuCommand(WMenu *menu, WMenuEntry *entry)
  110. {
  111.     WWindow *wwin = (WWindow*)entry->clientdata;
  112.     WApplication *wapp;
  113.     
  114.     CloseWindowMenu(menu->frame->screen_ptr);
  115.  
  116.     switch (entry->order) {
  117.      case MC_CLOSE:
  118.     /* send delete message */
  119.     wClientSendProtocol(wwin, _XA_WM_DELETE_WINDOW, LastTimestamp);
  120.     break;
  121.  
  122.      case MC_KILL:
  123.     wretain(wwin);
  124.     if (wPreferences.dont_confirm_kill
  125.         || wMessageDialog(menu->frame->screen_ptr, _("Kill Application"),
  126.                _("This will kill the application.\nAny unsaved changes will be lost.\nPlease confirm."),
  127.                _("Yes"), _("No"), NULL)==WAPRDefault) {
  128.         if (!wwin->flags.destroyed)
  129.         wClientKill(wwin);
  130.     }
  131.     wrelease(wwin);
  132.     break;
  133.  
  134.      case MC_MINIATURIZE:
  135.     if (wwin->flags.miniaturized) {
  136.         wDeiconifyWindow(wwin);
  137.     } else{
  138.         if (wwin->protocols.MINIATURIZE_WINDOW) {
  139.         wClientSendProtocol(wwin, _XA_GNUSTEP_WM_MINIATURIZE_WINDOW,
  140.                     LastTimestamp);
  141.         } else {
  142.         wIconifyWindow(wwin);
  143.         }
  144.     }
  145.     break;
  146.  
  147.      case MC_MAXIMIZE:
  148.     if (wwin->flags.maximized)
  149.         wUnmaximizeWindow(wwin);
  150.     else
  151.         wMaximizeWindow(wwin, MAX_VERTICAL|MAX_HORIZONTAL);
  152.     break;
  153.  
  154.      case MC_SHADE:
  155.     if (wwin->flags.shaded)
  156.         wUnshadeWindow(wwin);
  157.     else
  158.         wShadeWindow(wwin);
  159.     break;
  160.  
  161.      case MC_SELECT:
  162.     if (!wwin->flags.miniaturized)
  163.         wSelectWindow(wwin, !wwin->flags.selected);
  164.     else
  165.         wIconSelect(wwin->icon);
  166.     break;
  167.  
  168.      case MC_MOVERESIZE:
  169.         wKeyboardMoveResizeWindow(wwin);
  170.     break;
  171.  
  172.      case MC_PROPERTIES:
  173.     wShowInspectorForWindow(wwin);
  174.     break;
  175.  
  176.      case MC_HIDE:
  177.     wapp = wApplicationOf(wwin->main_window);
  178.     wHideApplication(wapp);
  179.     break;
  180.  
  181.     }
  182. }
  183.  
  184.  
  185. static void
  186. switchWSCommand(WMenu *menu, WMenuEntry *entry)
  187. {
  188.     WWindow *wwin = (WWindow*)entry->clientdata;
  189.  
  190.     wSelectWindow(wwin, False);
  191.     wWindowChangeWorkspace(wwin, entry->order);
  192. }
  193.  
  194.  
  195. static void
  196. makeShortcutCommand(WMenu *menu, WMenuEntry *entry)
  197. {
  198.     WWindow *wwin = (WWindow*)entry->clientdata;
  199.     WScreen *scr = wwin->screen_ptr;
  200.     int index = entry->order-WO_ENTRIES;
  201.  
  202.     if (scr->shortcutWindows[index]) {
  203.     WMFreeBag(scr->shortcutWindows[index]);
  204.     scr->shortcutWindows[index] = NULL;
  205.     }
  206.  
  207.     if (wwin->flags.selected && scr->selected_windows) {
  208.         WMBag *selwin = scr->selected_windows;
  209.     int i;
  210.     
  211.     scr->shortcutWindows[index] = WMCreateBag(4);
  212.  
  213.         for (i = 0; i < WMGetBagItemCount(selwin); i++) {
  214.         WWindow *tmp = WMGetFromBag(selwin, i);
  215.  
  216.         WMPutInBag(scr->shortcutWindows[index], tmp);
  217.         }
  218.     } else {
  219.     scr->shortcutWindows[index] = WMCreateBag(4);
  220.  
  221.     WMPutInBag(scr->shortcutWindows[index], wwin);
  222.     }
  223.  
  224.     wSelectWindow(wwin, !wwin->flags.selected);
  225.     XFlush(dpy);
  226.     wusleep(3000);
  227.     wSelectWindow(wwin, !wwin->flags.selected);
  228.     XFlush(dpy);
  229. }
  230.  
  231.  
  232. static void
  233. updateWorkspaceMenu(WMenu *menu)
  234. {
  235.     WScreen *scr = menu->frame->screen_ptr;
  236.     char title[MAX_WORKSPACENAME_WIDTH+1];
  237.     int i;
  238.     
  239.     if (!menu)
  240.     return;
  241.     
  242.     for (i=0; i<scr->workspace_count; i++) {
  243.     if (i < menu->entry_no) {
  244.         if (strcmp(menu->entries[i]->text,scr->workspaces[i]->name)!=0) {
  245.         free(menu->entries[i]->text);
  246.         strcpy(title, scr->workspaces[i]->name);
  247.         menu->entries[i]->text = wstrdup(title);
  248.         menu->flags.realized = 0;
  249.         }
  250.     } else {
  251.         strcpy(title, scr->workspaces[i]->name);
  252.  
  253.         wMenuAddCallback(menu, title, switchWSCommand, NULL);
  254.         
  255.         menu->flags.realized = 0;
  256.     }
  257.     }
  258.     
  259.     if (!menu->flags.realized)
  260.     wMenuRealize(menu);
  261. }
  262.  
  263.  
  264. static void
  265. updateMakeShortcutMenu(WMenu *menu, WWindow *wwin)
  266. {
  267.     WMenu *smenu = menu->cascades[menu->entries[MC_SHORTCUT]->cascade];
  268.     int i;
  269.     char *buffer;
  270.     KeyCode kcode;
  271.  
  272.     if (!smenu)
  273.     return;
  274.     
  275.     buffer = wmalloc(strlen(_("Set Shortcut"))+16);
  276.  
  277.     for (i=WO_ENTRIES; i<smenu->entry_no; i++) {
  278.     char *tmp;
  279.     int shortcutNo = i-WO_ENTRIES;
  280.     WMenuEntry *entry = smenu->entries[i];
  281.     WMBag *shortSelWindows = wwin->screen_ptr->shortcutWindows[shortcutNo];
  282.  
  283.     sprintf(buffer, "%s %i", _("Set Shortcut"), shortcutNo+1);
  284.     
  285.     if (!shortSelWindows) {
  286.         entry->flags.indicator_on = 0;
  287.     } else {
  288.         entry->flags.indicator_on = 1;
  289.         if (WMCountInBag(shortSelWindows, wwin))
  290.         entry->flags.indicator_type = MI_DIAMOND;
  291.         else
  292.         entry->flags.indicator_type = MI_CHECK;
  293.     }
  294.  
  295.     if (strcmp(buffer, entry->text)!=0) {
  296.         free(entry->text);
  297.         entry->text = wstrdup(buffer);
  298.         smenu->flags.realized = 0;
  299.     }
  300.  
  301.     kcode = wKeyBindings[WKBD_WINDOW1+shortcutNo].keycode;
  302.  
  303.     if (kcode) {
  304.         if ((tmp = XKeysymToString(XKeycodeToKeysym(dpy, kcode, 0)))
  305.         && (!entry->rtext || strcmp(tmp, entry->rtext)!=0)) {
  306.         if (entry->rtext)
  307.             free(entry->rtext);
  308.         entry->rtext = wstrdup(tmp);
  309.         smenu->flags.realized = 0;
  310.         }
  311.         wMenuSetEnabled(smenu, i, True);
  312.     } else {
  313.         wMenuSetEnabled(smenu, i, False);
  314.         if (entry->rtext) {
  315.         free(entry->rtext);
  316.         entry->rtext = NULL;
  317.         smenu->flags.realized = 0;
  318.         }
  319.     }
  320.     entry->clientdata = wwin;
  321.     }
  322.     free(buffer);
  323.     if (!smenu->flags.realized)
  324.     wMenuRealize(smenu);
  325. }
  326.  
  327.  
  328. static void
  329. updateOptionsMenu(WMenu *menu, WWindow *wwin)
  330. {    
  331.     WMenu *smenu = menu->cascades[menu->entries[MC_OPTIONS]->cascade];
  332.  
  333.     /* keep on top check */
  334.     smenu->entries[WO_KEEP_ON_TOP]->clientdata = wwin;
  335.     smenu->entries[WO_KEEP_ON_TOP]->flags.indicator_on = 
  336.         (wwin->frame->core->stacking->window_level == WMFloatingLevel)?1:0;
  337.     wMenuSetEnabled(smenu, WO_KEEP_ON_TOP, !wwin->flags.miniaturized);
  338.  
  339.     /* keep at bottom check */
  340.     smenu->entries[WO_KEEP_AT_BOTTOM]->clientdata = wwin;
  341.     smenu->entries[WO_KEEP_AT_BOTTOM]->flags.indicator_on =
  342.         (wwin->frame->core->stacking->window_level == WMSunkenLevel)?1:0;
  343.     wMenuSetEnabled(smenu, WO_KEEP_AT_BOTTOM, !wwin->flags.miniaturized);
  344.  
  345.     /* omnipresent check */
  346.     smenu->entries[WO_OMNIPRESENT]->clientdata = wwin;
  347.     smenu->entries[WO_OMNIPRESENT]->flags.indicator_on = IS_OMNIPRESENT(wwin);
  348.     
  349.     smenu->flags.realized = 0;
  350.     wMenuRealize(smenu);    
  351. }
  352.  
  353.  
  354. static WMenu*
  355. makeWorkspaceMenu(WScreen *scr)
  356. {
  357.     WMenu *menu;
  358.     
  359.     menu = wMenuCreate(scr, NULL, False);
  360.     if (!menu) {
  361.     wwarning(_("could not create submenu for window menu"));
  362.     return NULL;
  363.     }
  364.  
  365.     updateWorkspaceMenu(menu);
  366.     
  367.     return menu;
  368. }
  369.  
  370.  
  371. static WMenu*
  372. makeMakeShortcutMenu(WScreen *scr, WMenu *menu)
  373. {
  374.     /*
  375.     WMenu *menu;
  376.      */
  377.     int i;
  378. /*
  379.     menu = wMenuCreate(scr, NULL, False);
  380.     if (!menu) {
  381.     wwarning(_("could not create submenu for window menu"));
  382.     return NULL;
  383.     }
  384.  */
  385.  
  386.     for (i=0; i<MAX_WINDOW_SHORTCUTS; i++) {
  387.     WMenuEntry *entry;
  388.  
  389.     entry = wMenuAddCallback(menu, "", makeShortcutCommand, NULL);
  390.  
  391.     entry->flags.indicator = 1;
  392.     }
  393.  
  394.     return menu;
  395. }
  396.  
  397.  
  398.  
  399. static WMenu*
  400. makeOptionsMenu(WScreen *scr)
  401. {
  402.     WMenu *menu;
  403.     WMenuEntry *entry;
  404.  
  405.     menu = wMenuCreate(scr, NULL, False);
  406.     if (!menu) {
  407.     wwarning(_("could not create submenu for window menu"));
  408.     return NULL;
  409.     }
  410.  
  411.     entry = wMenuAddCallback(menu, _("Keep on top"), execWindowOptionCommand, 
  412.                  NULL);
  413.     entry->flags.indicator = 1;
  414.     entry->flags.indicator_type = MI_CHECK;
  415.  
  416.     entry = wMenuAddCallback(menu, _("Keep at bottom"), execWindowOptionCommand,
  417.                  NULL);
  418.     entry->flags.indicator = 1;
  419.     entry->flags.indicator_type = MI_CHECK;
  420.  
  421.     entry = wMenuAddCallback(menu, _("Omnipresent"), execWindowOptionCommand, 
  422.                  NULL);
  423.     entry->flags.indicator = 1;
  424.     entry->flags.indicator_type = MI_CHECK;
  425.  
  426.     return menu;
  427. }
  428.  
  429.  
  430. static WMenu*
  431. createWindowMenu(WScreen *scr)
  432. {
  433.     WMenu *menu;
  434.     KeyCode kcode;
  435.     WMenuEntry *entry;
  436.     char *tmp;
  437.  
  438.     menu = wMenuCreate(scr, NULL, False);
  439.     /* 
  440.      * Warning: If you make some change that affects the order of the 
  441.      * entries, you must update the command #defines in the top of
  442.      * this file.
  443.      */
  444.     entry = wMenuAddCallback(menu, _("Maximize"), execMenuCommand, NULL);
  445.     if (wKeyBindings[WKBD_MAXIMIZE].keycode!=0) {
  446.     kcode = wKeyBindings[WKBD_MAXIMIZE].keycode;
  447.     
  448.     if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, kcode, 0))))
  449.       entry->rtext = wstrdup(tmp);
  450.     }
  451.  
  452.     entry = wMenuAddCallback(menu, _("Miniaturize"), execMenuCommand, NULL);
  453.     
  454.     if (wKeyBindings[WKBD_MINIATURIZE].keycode!=0) {
  455.     kcode = wKeyBindings[WKBD_MINIATURIZE].keycode;
  456.     
  457.     if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, kcode, 0))))
  458.       entry->rtext = wstrdup(tmp);
  459.     }
  460.     
  461.     entry = wMenuAddCallback(menu, _("Shade"), execMenuCommand, NULL);
  462.     if (wKeyBindings[WKBD_SHADE].keycode!=0) {
  463.     kcode = wKeyBindings[WKBD_SHADE].keycode;
  464.     
  465.     if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, kcode, 0))))
  466.       entry->rtext = wstrdup(tmp);
  467.     }
  468.     
  469.     entry = wMenuAddCallback(menu, _("Hide"), execMenuCommand, NULL);
  470.     if (wKeyBindings[WKBD_HIDE].keycode!=0) {
  471.     kcode = wKeyBindings[WKBD_HIDE].keycode;
  472.     
  473.     if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, kcode, 0))))
  474.       entry->rtext = wstrdup(tmp);
  475.     }
  476.  
  477.     entry = wMenuAddCallback(menu, _("Resize/Move"), execMenuCommand, NULL);
  478.     if (wKeyBindings[WKBD_MOVERESIZE].keycode!=0) {
  479.     kcode = wKeyBindings[WKBD_MOVERESIZE].keycode;
  480.  
  481.     if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, kcode, 0))))
  482.       entry->rtext = wstrdup(tmp);
  483.     }
  484.  
  485.     entry = wMenuAddCallback(menu, _("Select"), execMenuCommand, NULL);
  486.     if (wKeyBindings[WKBD_SELECT].keycode!=0) {
  487.     kcode = wKeyBindings[WKBD_SELECT].keycode;
  488.  
  489.     if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, kcode, 0))))
  490.       entry->rtext = wstrdup(tmp);
  491.     }
  492.  
  493.     entry = wMenuAddCallback(menu, _("Move To"), NULL, NULL);
  494.     scr->workspace_submenu = makeWorkspaceMenu(scr);
  495.     if (scr->workspace_submenu)
  496.     wMenuEntrySetCascade(menu, entry, scr->workspace_submenu);
  497.  
  498.     entry = wMenuAddCallback(menu, _("Attributes..."), execMenuCommand, NULL);
  499.  
  500.     entry = wMenuAddCallback(menu, _("Options"), NULL, NULL);
  501.     wMenuEntrySetCascade(menu, entry, 
  502.              makeMakeShortcutMenu(scr, makeOptionsMenu(scr)));
  503.  
  504. /*
  505.     entry = wMenuAddCallback(menu, _("Select Shortcut"), NULL, NULL);
  506.     wMenuEntrySetCascade(menu, entry, makeMakeShortcutMenu(scr));
  507.  */
  508.  
  509.     entry = wMenuAddCallback(menu, _("Close"), execMenuCommand, NULL);
  510.     if (wKeyBindings[WKBD_CLOSE].keycode!=0) {
  511.     kcode = wKeyBindings[WKBD_CLOSE].keycode;
  512.     if (kcode && (tmp = XKeysymToString(XKeycodeToKeysym(dpy, kcode, 0))))
  513.       entry->rtext = wstrdup(tmp);
  514.     }
  515.     
  516.     entry = wMenuAddCallback(menu, _("Kill"), execMenuCommand, NULL);
  517.  
  518.     return menu;
  519. }
  520.  
  521.  
  522. void
  523. CloseWindowMenu(WScreen *scr)
  524. {
  525.     if (scr->window_menu) {
  526.     if (scr->window_menu->flags.mapped)
  527.         wMenuUnmap(scr->window_menu);
  528.     
  529.     if (scr->window_menu->entries[0]->clientdata) {
  530.         WWindow *wwin = (WWindow*)scr->window_menu->entries[0]->clientdata;
  531.  
  532.         wwin->flags.menu_open_for_me = 0;
  533.     }
  534.     scr->window_menu->entries[0]->clientdata = NULL;
  535.     }
  536. }
  537.  
  538.  
  539.  
  540. static void
  541. updateMenuForWindow(WMenu *menu, WWindow *wwin)
  542. {
  543.     WApplication *wapp = wApplicationOf(wwin->main_window);
  544.     WScreen *scr = wwin->screen_ptr;
  545.     int i;
  546.  
  547.     updateOptionsMenu(menu, wwin);
  548.  
  549.     updateMakeShortcutMenu(menu, wwin);
  550.  
  551.     wMenuSetEnabled(menu, MC_HIDE, wapp!=NULL 
  552.             && !WFLAGP(wapp->main_window_desc, no_appicon));
  553.     
  554.     wMenuSetEnabled(menu, MC_CLOSE, 
  555.             (wwin->protocols.DELETE_WINDOW
  556.              && !WFLAGP(wwin, no_closable)));
  557.  
  558.     if (wwin->flags.miniaturized) {
  559.     static char *text = NULL;
  560.     if (!text) text = _("Deminiaturize");
  561.  
  562.     menu->entries[MC_MINIATURIZE]->text = text;
  563.     } else {
  564.     static char *text = NULL;
  565.     if (!text) text = _("Miniaturize");
  566.  
  567.     menu->entries[MC_MINIATURIZE]->text = text;
  568.     }
  569.  
  570.     wMenuSetEnabled(menu, MC_MINIATURIZE, !WFLAGP(wwin, no_miniaturizable));
  571.  
  572.     if (wwin->flags.maximized) {
  573.     static char *text = NULL;
  574.     if (!text) text = _("Unmaximize");
  575.  
  576.     menu->entries[MC_MAXIMIZE]->text = text;
  577.     } else {
  578.     static char *text = NULL;
  579.     if (!text) text = _("Maximize");
  580.  
  581.     menu->entries[MC_MAXIMIZE]->text = text;
  582.     }
  583.     wMenuSetEnabled(menu, MC_MAXIMIZE, !WFLAGP(wwin, no_resizable));
  584.  
  585.  
  586.     wMenuSetEnabled(menu, MC_MOVERESIZE, !WFLAGP(wwin, no_resizable) 
  587.             && !wwin->flags.miniaturized);
  588.  
  589.     if (wwin->flags.shaded) {
  590.     static char *text = NULL;
  591.     if (!text) text = _("Unshade");
  592.  
  593.     menu->entries[MC_SHADE]->text = text;
  594.     } else {
  595.     static char *text = NULL;
  596.     if (!text) text = _("Shade");
  597.  
  598.     menu->entries[MC_SHADE]->text = text;
  599.     }
  600.  
  601.     wMenuSetEnabled(menu, MC_SHADE, !WFLAGP(wwin, no_shadeable)
  602.             && !wwin->flags.miniaturized);
  603.  
  604.     wMenuSetEnabled(menu, MC_DUMMY_MOVETO, !IS_OMNIPRESENT(wwin));
  605.     
  606.     if (!wwin->flags.inspector_open) {
  607.     wMenuSetEnabled(menu, MC_PROPERTIES, True);
  608.     } else {
  609.     wMenuSetEnabled(menu, MC_PROPERTIES, False);
  610.     }
  611.     
  612.     /* set the client data of the entries to the window */
  613.     for (i = 0; i < menu->entry_no; i++) {
  614.     menu->entries[i]->clientdata = wwin;
  615.     }
  616.  
  617.     for (i = 0; i < scr->workspace_submenu->entry_no; i++) {
  618.     scr->workspace_submenu->entries[i]->clientdata = wwin;
  619.     if (i == scr->current_workspace) {
  620.         wMenuSetEnabled(scr->workspace_submenu, i, False);
  621.     } else {
  622.         wMenuSetEnabled(scr->workspace_submenu, i, True);
  623.     }
  624.     }
  625.  
  626.     menu->flags.realized = 0;
  627.     wMenuRealize(menu);    
  628. }
  629.  
  630.  
  631. void
  632. OpenWindowMenu(WWindow *wwin, int x, int y, int keyboard)
  633. {
  634.     WMenu *menu;
  635.     WScreen *scr = wwin->screen_ptr;
  636.  
  637.     wwin->flags.menu_open_for_me = 1;
  638.  
  639.     if (!scr->window_menu) {
  640.     scr->window_menu = createWindowMenu(scr);
  641.     
  642.     /* hack to save some memory allocation/deallocation */
  643.     free(scr->window_menu->entries[MC_MINIATURIZE]->text);
  644.     free(scr->window_menu->entries[MC_MAXIMIZE]->text);
  645.     free(scr->window_menu->entries[MC_SHADE]->text);
  646.     } else {
  647.     updateWorkspaceMenu(scr->workspace_submenu);
  648.     }
  649.  
  650.     menu = scr->window_menu;
  651.     if (menu->flags.mapped) {
  652.     wMenuUnmap(menu);
  653.     if (menu->entries[0]->clientdata==wwin) {
  654.         return;
  655.     }
  656.     }
  657.  
  658.     updateMenuForWindow(menu, wwin);
  659.     
  660.     x -= menu->frame->core->width/2;
  661.     if (x + menu->frame->core->width > wwin->frame_x+wwin->frame->core->width)
  662.     x = wwin->frame_x+wwin->frame->core->width - menu->frame->core->width;
  663.     if (x < wwin->frame_x) 
  664.     x = wwin->frame_x;
  665.  
  666.     if (!wwin->flags.internal_window)
  667.     wMenuMapAt(menu, x, y, keyboard);
  668. }
  669.  
  670.  
  671. void
  672. OpenMiniwindowMenu(WWindow *wwin, int x, int y)
  673. {
  674.     WMenu *menu;
  675.     WScreen *scr = wwin->screen_ptr;
  676.  
  677.     wwin->flags.menu_open_for_me = 1;
  678.  
  679.     if (!scr->window_menu) {
  680.     scr->window_menu = createWindowMenu(scr);
  681.     
  682.     /* hack to save some memory allocation/deallocation */
  683.     free(scr->window_menu->entries[MC_MINIATURIZE]->text);
  684.     free(scr->window_menu->entries[MC_MAXIMIZE]->text);
  685.     free(scr->window_menu->entries[MC_SHADE]->text);    
  686.     } else {
  687.     updateWorkspaceMenu(scr->workspace_submenu);
  688.     }
  689.  
  690.     menu = scr->window_menu;
  691.     if (menu->flags.mapped) {
  692.     wMenuUnmap(menu);
  693.     if (menu->entries[0]->clientdata==wwin) {
  694.         return;
  695.     }
  696.     }
  697.  
  698.     updateMenuForWindow(menu, wwin);
  699.     
  700.     x -= menu->frame->core->width/2;
  701.  
  702.     wMenuMapAt(menu, x, y, False);
  703. }
  704.  
  705.